package com.jy.appmarket.screenlock.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.DisplayMetrics;
import android.util.Log;

import com.rad.net.protocol.android.utils.LogUtils;

/**
 * 类说明： 处理加载资源文件的类
 * 
 * @author kalui.huang
 * @date 2014-12-18
 * @version 1.0
 */
public class ImageUtils {
	public final static String TAG = "ImageUtils";

	private MemoryCache mMemoryCache;

	public ImageUtils() {
		mMemoryCache = new MemoryCache();
	}

	/**
	 * 使用此方法在加载资源文件是就不会被重复创建，使用完成需在退出时使用{@link #clearCache()}
	 * 
	 * @param resId
	 *            资源id
	 * @param compress
	 *            是否压缩
	 * @param requiredSize
	 *            需要压缩时压缩后的长或宽，compress必须未true才可使用
	 * @return
	 */
	public Bitmap getBitmap(Context context, int resId, boolean compress, int requiredSize) {
		Bitmap bitmap = mMemoryCache.get(resId);
		if (bitmap != null) {
			LogUtils.d(TAG, "get bitmap from cache..");
		} else {
			LogUtils.d(TAG, "get bitmap from decodeResource..");
			bitmap = decodeResourceFile(context, resId, compress, requiredSize);
			mMemoryCache.put(resId, bitmap);
		}
		return bitmap;
	}

	/**
	 * {@link #getBitmap(int, boolean, int)},默认不压缩
	 * 
	 * @param resId
	 * @return
	 */
	public Bitmap getBitmap(Context context, int resId) {
		return getBitmap(context, resId, false, 0);
	}

	/**
	 * 从Assets中读取图片
	 */
	public Bitmap getBitmapFromAsserts(Context context, String imageName) {
		if (imageName == null || imageName.length() == 0) {
			return null;
		}
		AssetManager am = context.getResources().getAssets();
		Bitmap bitmap = mMemoryCache.get(imageName);
		if (bitmap != null) {
			LogUtils.d(TAG, "get bitmap from cache..");
		} else {
			try {
				BitmapFactory.Options op = new BitmapFactory.Options();
				op.inPreferredConfig = Bitmap.Config.RGB_565;
				op.inPurgeable = true;
				op.inInputShareable = true;

				InputStream is = am.open(imageName);
				bitmap = BitmapFactory.decodeStream(is, null, op);
				is.close();
			} catch (Exception e) {
				e.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile erro.." + e.toString());
			} catch (OutOfMemoryError oom) {
				oom.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile OOM.." + oom.toString());
			}
			LogUtils.d(TAG, "get bitmap from decodeAssertsStream..");
			mMemoryCache.put(imageName, bitmap);
		}
		return bitmap;
	}

	public Bitmap getBitmapDecodeFile(String pathName) {
		if (pathName == null || pathName.length() == 0) {
			return null;
		}
		Bitmap bitmap = mMemoryCache.get(pathName);
		if (bitmap != null) {
			LogUtils.d(TAG, "get bitmap from cache..");
		} else {
			try {
				BitmapFactory.Options op = new BitmapFactory.Options();
				// op.inPreferredConfig = Bitmap.Config.RGB_565;
				op.inPreferredConfig = Bitmap.Config.ALPHA_8;
				op.inPurgeable = true;
				op.inInputShareable = true;
				// bitmap = BitmapFactory.decodeFile(pathName, op);
				FileInputStream stream = new FileInputStream(new File(pathName));
				bitmap = BitmapFactory.decodeStream(stream, null, op);
				stream.close();
			} catch (Exception e) {
				e.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile erro.." + e.toString());
			} catch (OutOfMemoryError oom) {
				oom.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile OOM.." + oom.toString());
			}
			LogUtils.d(TAG, "get bitmap from decodeFile..");
			mMemoryCache.put(pathName, bitmap);
		}
		return bitmap;
	}

	public Bitmap getBitmapDecodeFile(String pathName, boolean compress, int requiredSize) {
		if (pathName == null || pathName.length() == 0) {
			return null;
		}
		Bitmap bitmap = mMemoryCache.get(pathName);
		if (bitmap != null) {
			LogUtils.d(TAG, "get bitmap from cache..");
		} else {
			try {
				if (compress && requiredSize > 0) {
					BitmapFactory.Options op = new BitmapFactory.Options();
					op.inJustDecodeBounds = true;
					bitmap = BitmapFactory.decodeFile(pathName, op);

					// Find the correct scale value. It should be the power of
					// 2.
					int width_tmp = op.outWidth;
					int height_tmp = op.outHeight;
					int scale = 1;
					while (true) {
						if (width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize)
							break;
						width_tmp /= 2;
						height_tmp /= 2;
						scale *= 2;
					}

					BitmapFactory.Options op2 = new BitmapFactory.Options();
					op2.inSampleSize = scale;
					bitmap = BitmapFactory.decodeFile(pathName, op2);
				} else {
					BitmapFactory.Options op = new BitmapFactory.Options();
					op.inPreferredConfig = Bitmap.Config.RGB_565;
					op.inPurgeable = true;
					op.inInputShareable = true;
					bitmap = BitmapFactory.decodeFile(pathName, op);
				}
			} catch (Exception e) {
				e.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile erro.." + e.toString());
			} catch (OutOfMemoryError oom) {
				oom.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile OOM.." + oom.toString());
			}
			LogUtils.d(TAG, "get bitmap from decodeFile..");
			mMemoryCache.put(pathName, bitmap);
		}
		return bitmap;
	}

	public Bitmap getBitmapDecodeResForWallpaper(Context context, int resId) {
		Bitmap bitmap = mMemoryCache.get(resId);
		if (bitmap != null) {
			LogUtils.d(TAG, "get bitmap from cache..");
		} else {
			try {
				BitmapFactory.Options op = new BitmapFactory.Options();
				op.inJustDecodeBounds = true;
				BitmapFactory.decodeResource(context.getResources(), resId, op);
				DisplayMetrics dm = context.getResources().getDisplayMetrics();
				int height = op.outHeight;
				if (height > dm.heightPixels) {
					int sample = height / dm.heightPixels;
					Log.d(TAG, "sample:" + sample);
					op.inSampleSize = sample;
				}
				op.inJustDecodeBounds = false;
				op.inPreferredConfig = Bitmap.Config.ALPHA_8;
				op.inPurgeable = true;
				op.inInputShareable = true;
				bitmap = BitmapFactory.decodeResource(context.getResources(), resId, op);
			} catch (Exception e) {
				e.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile erro.." + e.toString());
			} catch (OutOfMemoryError oom) {
				oom.printStackTrace();
				LogUtils.w(TAG, "decodeResourceFile OOM.." + oom.toString());
			}
			LogUtils.d(TAG, "get bitmap from decodeResource..");
			mMemoryCache.put(resId, bitmap);
		}
		return bitmap;
	}

	private Bitmap decodeResourceFile(Context context, int resId, boolean compress, int requiredSize) {
		if (resId == 0) {
			return null;
		}
		Bitmap bitmap = null;
		try {
			if (compress && requiredSize > 0) {
				BitmapFactory.Options op = new BitmapFactory.Options();
				op.inJustDecodeBounds = true;
				BitmapFactory.decodeResource(context.getResources(), resId, op);

				// Find the correct scale value. It should be the power of 2.
				int width_tmp = op.outWidth;
				int height_tmp = op.outHeight;
				int scale = 1;
				while (true) {
					if (width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize)
						break;
					width_tmp /= 2;
					height_tmp /= 2;
					scale *= 2;
				}

				BitmapFactory.Options op2 = new BitmapFactory.Options();
				op2.inSampleSize = scale;
				bitmap = BitmapFactory.decodeResource(context.getResources(), resId, op2);
			} else {
				BitmapFactory.Options op = new BitmapFactory.Options();
				op.inPreferredConfig = Bitmap.Config.RGB_565;
				op.inPurgeable = true;
				op.inInputShareable = true;
				bitmap = BitmapFactory.decodeResource(context.getResources(), resId, op);
			}
		} catch (Exception e) {
			e.printStackTrace();
			LogUtils.w(TAG, "decodeResourceFile erro.." + e.toString());
		} catch (OutOfMemoryError oom) {
			oom.printStackTrace();
			LogUtils.w(TAG, "decodeResourceFile OOM.." + oom.toString());
		}
		return bitmap;
	}

	/**
	 * 清理缓存，在activity退出时清理
	 */
	public void clearCache() {
		mMemoryCache.clear();
	}

}
